home *** CD-ROM | disk | FTP | other *** search
- /*
- avwm 0.4 / Amiga Virtual Workbench Manager
- 5/2/93 Bernhard Fastenrath
- Public Domain
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <signal.h>
- #include <dos.h>
- #include <exec/types.h>
- #include <devices/timer.h>
- #include <graphics/rastport.h>
- #include <intuition/intuitionbase.h>
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <proto/graphics.h>
- #include <proto/intuition.h>
-
- #include "callbacks.h"
- #include "avwm.h"
- #include "wbwm.h"
-
- const char *Version = VERSION;
-
- struct IntuitionBase *IntuitionBase = NULL;
- struct timerequest *TimerIO = NULL;
- struct MsgPort *TimerPort = NULL;
- struct Window *Win = NULL,
- *LastActiveWindow = NULL;
- struct RastPort *Rp;
- short Screenwidth, Screenheight,
- VisWidth, VisHeight;
- struct List VWinA[2];
- int Options = OPT_NO_SETF | OPT_MOVE_SCREEN,
- VWIndex = 0, Dx, Dy,
- Action = ACT_NONE, Area = 0,
- Seconds = 2, MSeconds = 0;
- Offset = 11;
- ULONG WMSigBit = -1, WMSig;
- struct vWindow *Cvw = NULL;
- char *PubScreenName = "Workbench";
-
- int
- main (int argc, char *argv[])
- {
- struct Screen *Lock;
- struct NewWindow NewWin;
- int argn = 1;
- char optc;
-
- while (argn < argc)
- if (argopt (argc, argv, "OcS", &argn, &optc))
- switch (optc) {
- case 'O':
- Offset = atoi (argv[argn-1] + (argv[argn-1][0] == '-' ? 2 : 0));
- break;
- case 'h':
- printf ("Amiga Virtual Workbench Manager %d.%d\n", VER_NUM, REV_NUM);
- printf ("Options: -t don't open timer device.\n");
- printf (" -c <n> check windows every n seconds (default: 2s).\n");
- printf (" -s use SetFunction () (by default disabled now).\n");
- printf (" -m use MoveWindow (expects double v. screen size) instead of\n");
- printf (" MoveScreen (expects triple h. and double v. screen size).\n");
- printf (" -S Name of public screen (default: Workbench).\n");
- exit (0);
- case 'c':
- Seconds = atoi (argv[argn-1] + (argv[argn-1][0] == '-' ? 2 : 0));
- if (Seconds == 0) MSeconds = 250;
- break;
- case 't':
- Options |= OPT_NO_TIMER;
- break;
- case 's':
- Options &= ~OPT_NO_SETF;
- break;
- case 'm':
- Options &= ~OPT_MOVE_SCREEN;
- break;
- case 'S':
- PubScreenName = argv[argn-1] + (argv[argn-1][0] == '-' ? 2 : 0);
- break;
- default:
- printf ("Invalid Option: \"-%c\" (try '%s -h')\n", optc, argv[0]);
- exit (20);
- }
- else
- argn++;
-
- InitListHeader ((struct MinList *) &VWinA[0]);
- InitListHeader ((struct MinList *) &VWinA[1]);
-
- if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library", 37L))) {
- printf ("%s: Can't open intuition library 37.x.\n", Version);
- exit_avwm (1);
- }
- if ((Lock = LockPubScreen (PubScreenName)) == NULL) {
- printf ("%s: Can't lock public screen '%s'.\n", Version, PubScreenName);
- exit_avwm (1);
- }
- Screenwidth = Lock -> Width;
- Screenheight = Lock -> Height;
-
- if (Options & OPT_MOVE_SCREEN) {
- VisWidth = Screenwidth / 3;
- VisHeight = Screenheight / 2;
- }
- else {
- VisWidth = Screenwidth;
- VisHeight = Screenheight / 2;
- }
- NewWin.LeftEdge = VisWidth - AVWM_WIDTH;
- NewWin.TopEdge = 12;
- NewWin.Width = AVWM_WIDTH;
- NewWin.Height = AVWM_HEIGHT;
- NewWin.DetailPen = 0;
- NewWin.BlockPen = 1;
- NewWin.Title = "Virtual Desktop";
- NewWin.Flags = WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | SMART_REFRESH |
- GIMMEZEROZERO | ACTIVATE | RMBTRAP | REPORTMOUSE;
- NewWin.IDCMPFlags = MOUSEBUTTONS | CLOSEWINDOW | REFRESHWINDOW | MOUSEMOVE;
- NewWin.Type = PUBLICSCREEN;
- NewWin.FirstGadget = NULL;
- NewWin.CheckMark = NULL;
- NewWin.Screen = Lock;
- NewWin.BitMap = NULL;
- NewWin.MinWidth = 0;
- NewWin.MinHeight = 0;
- NewWin.MaxWidth = 0;
- NewWin.MaxHeight = 0;
-
- if (!(Win = OpenWindow (&NewWin))) {
- UnlockPubScreen (NULL, Lock);
- printf ("%s: Can't open window.\n", Version);
- exit_avwm (20);
- }
- UnlockPubScreen (NULL, Lock);
- Rp = Win -> RPort;
-
- AddCallback (Win, close_window, CLOSEWINDOW);
- AddCallback (Win, mouse_event, MOUSEBUTTONS);
- AddCallback (Win, refresh_window, REFRESHWINDOW);
- AddCallback (Win, mouse_move, MOUSEMOVE);
-
- if ((Options & OPT_NO_TIMER) == 0)
- {
- init_timer ();
- AddPortCallback (TimerPort, (callback) timer_event, 0);
- }
-
- if ((Options & OPT_NO_SETF) == 0)
- {
- if ((WMSigBit = AllocSignal (-1)) == -1)
- {
- printf ("%s: Can't allocate Signal.\n", Version);
- exit_avwm (20);
- }
- start_window_monitor ();
- WMSig = 1L << WMSigBit;
- SetSignalCallback (WMSig, (callback) workbench_monitor_event);
- }
- refresh_graphic ();
-
- AppMainLoop ();
-
- exit_avwm (0);
- }
-
- void
- exit_avwm (int code)
- {
- struct Node *node;
-
- stop_window_monitor ();
- while (node = RemTail (&VWinA[0]))
- free (node);
- while (node = RemTail (&VWinA[1]))
- free (node);
- if (WMSigBit != -1) FreeSignal (WMSigBit);
- if (Win) CloseWindow (Win);
- if ((Options & OPT_NO_SETF) == 0) Delay (100);
- if (TimerIO) {
- AbortIO ((struct IORequest *) TimerIO);
- WaitIO ((struct IORequest *) TimerIO);
- CloseDevice ((struct IORequest *) TimerIO);
- DeleteExtIO ((struct IORequest *) TimerIO, sizeof (struct timerequest));
- }
- if (TimerPort) DeletePort (TimerPort);
- RemoveAllCallbacks ();
- if (IntuitionBase) CloseLibrary ((struct Library *) IntuitionBase);
- exit (code);
- }
-
- void
- init_timer ()
- {
- int err;
-
- if (!(TimerPort = CreatePort (0, 0)))
- {
- printf ("%s: Can't create message port.\n", Version);
- exit_avwm (1);
- }
- if (!(TimerIO = (struct timerequest *) CreateExtIO (TimerPort, sizeof (struct timerequest))))
- {
- printf ("%s: Out of memory.\n", Version);
- exit_avwm (1);
- }
- if (err = OpenDevice (TIMERNAME, UNIT_VBLANK, (struct IORequest *) TimerIO, 0))
- {
- printf ("%s: Can't open timer.device (code %d).\n", Version, err);
- exit_avwm (1);
- }
- TimerIO -> tr_time.tv_secs = Seconds;
- TimerIO -> tr_time.tv_micro = MSeconds;
- TimerIO -> tr_node.io_Command = TR_ADDREQUEST;
- SendIO ((struct IORequest *) TimerIO);
- }
-
- struct Window *
- assert_window (struct Window *search)
- {
- struct Window *window;
-
- for (window = Win -> WScreen -> FirstWindow; window; window = window -> NextWindow)
- if (search == window) return window;
-
- return NULL;
- }
-
- void
- draw_box (short color, short x1, short y1, short x2, short y2, struct RastPort *rp)
- {
- SetAPen (rp, GREY);
-
- RectFill (rp, x1, y1, x2, y2);
-
- SetAPen (rp, color);
-
- Move (rp, x1, y1);
- Draw (rp, x2, y1);
- Draw (rp, x2, y2);
- Draw (rp, x1, y2);
- Draw (rp, x1, y1);
- }
-
- void
- draw_frame (short color, short x1, short y1, short x2, short y2, struct RastPort *rp)
- {
- SetAPen (rp, color);
-
- Move (rp, x1, y1);
- Draw (rp, x2, y1);
- Draw (rp, x2, y2);
- Draw (rp, x1, y2);
- Draw (rp, x1, y1);
- }
-
- void
- draw_vwindow (int color, struct vWindow *vw)
- {
- int x, y;
-
- x = vw -> sx + AREA_X (vw -> area) * SUB_WIDTH;
- y = vw -> sy + AREA_Y (vw -> area) * SUB_HEIGHT;
-
- draw_frame (color, x, y, x + vw -> sw, y + vw -> sh, Rp);
- }
-
- void
- redraw_graphic ()
- {
- struct vWindow *vw;
- struct List *vwl;
- short color;
- int x, y;
-
- vwl = &VWinA[VWIndex];
-
- SetDrMd (Rp, JAM2);
- SetAPen (Rp, GREY);
-
- RectFill (Rp, 0, 0, AVWM_WIDTH, AVWM_HEIGHT);
-
- SetAPen (Rp, BLACK);
-
- Move (Rp, 0, SUB_HEIGHT); Draw (Rp, SUB_WIDTH * 3, SUB_HEIGHT);
- Move (Rp, SUB_WIDTH, 0); Draw (Rp, SUB_WIDTH, SUB_HEIGHT * 2);
- Move (Rp, SUB_WIDTH * 2, 0); Draw (Rp, SUB_WIDTH * 2, SUB_HEIGHT * 2);
-
- for (vw = (struct vWindow *) vwl -> lh_TailPred;
- vw -> node.ln_Pred; vw = (struct vWindow *) vw -> node.ln_Pred)
- {
- if (IntuitionBase -> ActiveWindow == vw -> window)
- color = BLUE;
- else
- color = BLACK;
-
- x = vw -> sx + AREA_X (vw -> area) * SUB_WIDTH;
- y = vw -> sy + AREA_Y (vw -> area) * SUB_HEIGHT;
-
- draw_box (color, x, y, x + vw -> sw, y + vw -> sh, Rp);
- }
- }
-
- void
- refresh_graphic ()
- {
- struct Window *window;
- struct vWindow *vw;
- short change = 0;
- BYTE pos;
- struct List *vwl, *vwl2;
- struct Layer *layer;
- int area;
-
- Forbid ();
-
- if (IntuitionBase -> FirstScreen != Win -> WScreen
- && IntuitionBase -> ActiveScreen != Win -> WScreen)
- {
- Permit ();
- return; /* Screen not in use, event ignored */
- }
- vwl = &VWinA[VWIndex];
- VWIndex = 1 - VWIndex;
- vwl2 = &VWinA[VWIndex];
-
- if (LastActiveWindow != IntuitionBase -> ActiveWindow)
- {
- LastActiveWindow = IntuitionBase -> ActiveWindow;
- change = 1;
- }
-
- /* Set the change status of all windows to "unknown" */
- for (vw = (struct vWindow *) vwl -> lh_Head;
- vw -> node.ln_Succ; vw = (struct vWindow *) vw -> node.ln_Succ)
- {
- vw -> changed = -1;
- }
-
- /* Find the front layer */
- for (layer = Win -> WScreen -> FirstWindow -> WLayer;
- layer -> front; layer = layer -> front);
-
- /* Sort the virtual window list like the layers of the screen
- and check if size, position or priority of any window changed
- */
- for (pos = HIGH_PRI; layer -> back; pos--, layer = layer -> back)
- {
- if (!(window = layer -> Window)) continue;
-
- for (vw = (struct vWindow *) vwl -> lh_Head;
- vw -> node.ln_Succ; vw = (struct vWindow *) vw -> node.ln_Succ)
- {
- if (vw -> window == window)
- {
- if (vw -> changed != -1) break;
-
- vw -> changed = 0; /* Window has moved? */
-
- if (vw -> ox != window -> LeftEdge)
- { vw -> ox = window -> LeftEdge; change = vw -> changed = 1; }
- if (vw -> oy != window -> TopEdge)
- { vw -> oy = window -> TopEdge; change = vw -> changed = 1; }
- if (vw -> ow != window -> Width)
- { vw -> ow = window -> Width; change = vw -> changed = 1; }
- if (vw -> oh != window -> Height)
- { vw -> oh = window -> Height; change = vw -> changed = 1; }
-
- if (vw -> changed)
- {
- /* Window has moved into another area? */
- area = AREA (window -> LeftEdge, window -> TopEdge);
-
- /* Don't change the area if MoveWindow is used
- and the window is invisible
- because it will always be found in the lower
- "invisible" part of the screen
- */
- if (Options & OPT_MOVE_SCREEN)
- vw -> area = area;
- else if (area == 0)
- vw -> area = Area;
-
- #ifdef DEBUG
- printf ("Window %d moved to %d,%d in area %d.\n", vw -> window, vw -> ox, vw -> oy, area);
- #endif
- }
-
- if (vw -> node.ln_Pri != pos) /* Window order has changed */
- {
- #ifdef DEBUG
- printf ("Window order has changed. (area %d) [was: %d, is: %d]\n", vw->area, vw->node.ln_Pri, pos);
- #endif
- vw -> node.ln_Pri = pos;
- change = 1;
- }
- break;
- }
- }
-
- if (!vw -> node.ln_Succ) /* New window has been opened */
- {
- if (!(vw = Malloc (struct vWindow))) {
- Permit ();
- printf ("%s: Memory low!.\n", Version);
- exit_avwm (1);
- }
- vw -> area = AREA (window -> LeftEdge, window -> TopEdge);
-
- /* Set the area to the area currently displayed in area 0 */
- if (!(Options & OPT_MOVE_SCREEN) && vw -> area == 0)
- vw -> area = Area;
-
- #ifdef DEBUG
- printf ("Adding window to area %d.\n", vw -> area);
- #endif
- vw -> changed = 2;
- vw -> window = window;
- vw -> node.ln_Pri = pos;
- vw -> ox = window -> LeftEdge;
- vw -> oy = window -> TopEdge;
- vw -> ow = window -> Width;
- vw -> oh = window -> Height;
-
- AddHead (vwl, (struct Node *) vw);
-
- change = 1;
- }
- }
- Permit ();
-
- while (vw = (struct vWindow *) RemTail (vwl))
- {
- if (vw -> changed == -1) { /* Window has been closed */
- free (vw);
- change = 1;
- #ifdef DEBUG
- printf ("Window removed.\n");
- #endif
- }
- else /* If the window order is unchanged this is just an AddHead() */
- Enqueue (vwl2, (struct Node *) vw);
- }
-
- if (change) /* Don't draw if nothing has happened */
- {
- if (Options & OPT_MOVE_SCREEN)
- for (vw = (struct vWindow *) vwl2 -> lh_TailPred;
- vw -> node.ln_Pred; vw = (struct vWindow *) vw -> node.ln_Pred)
- {
- vw -> sx = (vw -> ox % VisWidth) * SUB_WIDTH / VisWidth;
- vw -> sy = (vw -> oy % VisHeight) * SUB_HEIGHT / VisHeight;
- vw -> sw = vw -> ow * SUB_WIDTH / VisWidth;
- vw -> sh = vw -> oh * SUB_HEIGHT / VisHeight;
- }
- else
- for (vw = (struct vWindow *) vwl2 -> lh_TailPred;
- vw -> node.ln_Pred; vw = (struct vWindow *) vw -> node.ln_Pred)
- {
- /* ignore window's position (but not size)
- if it is invisible
- */
- if (vw -> area == Area || vw -> changed == 2)
- {
- vw -> sx = (vw -> ox % VisWidth) * SUB_WIDTH / VisWidth;
- vw -> sy = (vw -> oy % VisHeight) * SUB_HEIGHT / VisHeight;
- }
- vw -> sw = vw -> ow * SUB_WIDTH / VisWidth;
- vw -> sh = vw -> oh * SUB_HEIGHT / VisHeight;
- }
- redraw_graphic ();
- }
- }
-
- struct vWindow *
- find_window (int x, int y)
- {
- struct vWindow *vw;
- struct List *vwl;
- int area;
-
- vwl = &VWinA[VWIndex];
-
- area = vAREA (x, y); x %= SUB_WIDTH; y %= SUB_HEIGHT;
-
- for (vw = (struct vWindow *) vwl -> lh_Head;
- vw -> node.ln_Succ; vw = (struct vWindow *) vw -> node.ln_Succ)
- {
- if (x > vw->sx && y > vw->sy && x < vw->sw + vw->sx && y < vw->sh + vw->sy
- && area == vw -> area)
- return vw;
- }
- return NULL;
- }
-
- int
- close_window (struct IntuiMessage *msg, struct Callback *cb)
- {
- exit_avwm (0);
- return 0;
- }
-
- int
- refresh_window (struct IntuiMessage *msg, struct Callback *cb)
- {
- return 0;
- }
-
- int
- timer_event (struct timerequest *msg, struct Callback *cb)
- {
- TimerIO -> tr_time.tv_secs = Seconds;
- TimerIO -> tr_time.tv_micro = MSeconds;
- TimerIO -> tr_node.io_Command = TR_ADDREQUEST;
- SendIO ((struct IORequest *) TimerIO);
-
- if (!Action) refresh_graphic ();
- return 0;
- }
-
- void
- workbench_monitor_event (int signals)
- {
- #ifdef xDEBUG
- printf ("Monitor Event (signal: %d).\n", signals);
- #endif
- if (!Action) refresh_graphic ();
- #ifdef xDEBUG
- else printf ("Monitor Event ignored.\n");
- #endif
- }
-
- int
- mouse_move (struct IntuiMessage *msg, struct Callback *cb)
- {
- if (Action == ACT_NONE) return 0;
-
- if (Action == ACT_MOVE_WIN)
- {
- draw_vwindow (WHITE, Cvw);
- Cvw -> sx += msg -> MouseX - Dx;
- Cvw -> sy += msg -> MouseY - Dy;
- Dx = msg -> MouseX;
- Dy = msg -> MouseY;
- draw_vwindow (WHITE, Cvw);
- }
- return 0;
- }
-
- static void
- change_area (int x, int y)
- {
- struct vWindow *vw;
- WORD dx, dy;
- short oldarea;
-
- oldarea = Area;
- Area = vAREA (x, y);
-
- if (oldarea == Area)
- return;
-
- #ifdef xDEBUG
- printf ("Visible area was %d, now %d.\n", oldarea, Area);
- #endif
-
- if (Options & OPT_MOVE_SCREEN)
- {
- dx = VisWidth * AREA_X (Area) + Win -> WScreen -> LeftEdge;
- dy = VisHeight * AREA_Y (Area) + Win -> WScreen -> TopEdge;
-
- MoveScreen (Win -> WScreen, -dx, -dy);
-
- MoveWindow (Win, dx, dy);
- }
- else
- {
- for (vw = (struct vWindow *) VWinA[VWIndex].lh_Head;
- vw -> node.ln_Succ; vw = (struct vWindow *) vw -> node.ln_Succ)
- {
- if (vw -> window == Win) /* The awvm window always stays */
- {
- vw -> area = Area;
- }
- else if (vw -> area == oldarea)
- {
- Forbid ();
-
- if (assert_window (vw -> window)) /* Move it away */
- {
- ChangeWindowBox (vw -> window,
- 0, VisHeight,
- vw -> window -> Width,
- vw -> window -> Height);
- }
-
- Permit ();
- }
- #if 0 /* Remove, then add windows -- this looks better and is probably faster */
- else if (vw -> area == Area)
- #else
- }
- for (vw = (struct vWindow *) VWinA[VWIndex].lh_Head;
- vw -> node.ln_Succ; vw = (struct vWindow *) vw -> node.ln_Succ)
- {
- if (vw -> area == Area && vw -> window != Win)
- #endif
- {
- Forbid ();
-
- if (assert_window (vw -> window)) /* Make it visible */
- {
- ChangeWindowBox (vw -> window,
- vw -> sx * VisWidth / SUB_WIDTH + Offset,
- vw -> sy * VisHeight / SUB_HEIGHT + Offset,
- vw -> window -> Width,
- vw -> window -> Height);
- }
-
- Permit ();
- }
- }
- }
- }
-
- int
- mouse_event (struct IntuiMessage *msg, struct Callback *cb)
- {
- static ULONG lsecs = 0, lmicros = 0;
- static int start_x, start_y;
- ULONG secs = 0, micros = 0;
- int x, y;
-
- x = Win -> GZZMouseX;
- y = Win -> GZZMouseY;
-
- switch (msg -> Code)
- {
- case SELECTDOWN:
- CurrentTime (&secs, µs);
- if (DoubleClick (lsecs, lmicros, secs, micros))
- {
- lsecs = lmicros = 0;
- change_area (x, y);
- }
- else
- {
- if (Cvw = find_window (x, y))
- {
- Action = ACT_MOVE_WIN;
- SetDrMd (Rp, COMPLEMENT);
- draw_vwindow (WHITE, Cvw); /* Create temporary image */
- Dx = msg -> MouseX;
- Dy = msg -> MouseY;
-
- start_x = Cvw -> sx;
- start_y = Cvw -> sy;
- }
- lsecs = secs;
- lmicros = micros;
- }
- break;
-
- case SELECTUP:
- if (Cvw)
- {
- int area;
-
- Action = ACT_NONE;
- draw_vwindow (WHITE, Cvw); /* Remove temporary image */
- SetDrMd (Rp, JAM2);
-
- area = vAREA (x, y);
-
- while (Cvw -> sx < 0) Cvw -> sx += SUB_WIDTH;
- while (Cvw -> sy < 0) Cvw -> sy += SUB_HEIGHT;
- Cvw -> sx %= SUB_WIDTH;
- Cvw -> sy %= SUB_HEIGHT;
-
- if ((start_x + 1 > Cvw -> sx && start_x - 1 < Cvw -> sx &&
- start_y + 1 > Cvw -> sy && start_y - 1 < Cvw -> sy &&
- area == Cvw -> area) ||
- (area != Cvw -> area && Cvw -> window == Win))
- {
- Cvw = NULL;
- break;
- }
-
- Forbid ();
-
- if (assert_window (Cvw -> window))
- {
- struct Window *win;
-
- win = Cvw -> window;
-
- if (area == Area) /* Destination area is visible */
- {
- if (Options & OPT_MOVE_SCREEN) {
- ChangeWindowBox (Cvw -> window,
- Cvw -> sx * VisWidth / SUB_WIDTH + AREA_X (area) * VisWidth,
- Cvw -> sy * VisHeight / SUB_HEIGHT + AREA_Y (area) * VisHeight,
- win -> Width, win -> Height);
- }
- else {
- ChangeWindowBox (Cvw -> window,
- Cvw -> sx * VisWidth / SUB_WIDTH,
- Cvw -> sy * VisHeight / SUB_HEIGHT,
- win -> Width, win -> Height);
- }
- }
- else
- {
- if (Options & OPT_MOVE_SCREEN) { /* Six areas (3 * 2) */
- ChangeWindowBox (Cvw -> window,
- Cvw -> sx * VisWidth / SUB_WIDTH + AREA_X (area) * VisWidth,
- Cvw -> sy * VisHeight / SUB_HEIGHT + AREA_Y (area) * VisHeight,
- win -> Width, win -> Height);
- }
- else { /* Two `real' areas (1 * 2) */
- ChangeWindowBox (Cvw -> window,
- 0, VisHeight, win -> Width, win -> Height);
- }
- }
- Permit ();
-
- Cvw -> area = area;
- }
- else {
- Permit ();
- DisplayBeep (Win -> WScreen);
- }
- Cvw = NULL;
-
- redraw_graphic ();
- }
- break;
-
-
- case MIDDLEDOWN: break;
- case MIDDLEUP:
- change_area (x, y);
- break;
-
- case MENUDOWN: break;
- case MENUUP:
- if (Cvw) break;
- if (Cvw = find_window (x, y))
- {
- Forbid ();
- if (assert_window (Cvw -> window))
- {
- ZipWindow (Cvw -> window);
- }
- Permit ();
- Cvw = NULL;
- }
- break;
-
- default: break;
- }
- return 0;
- }
-
-
- /* Shouldn't this disable SAS/C's ctrl-c handling? */
- void CXBRK () {}
- void chkabort () {}
-
-